c3b12d0f8d57a6a7626bef89633ae968144c8ef1,src/frontend/org/voltdb/planner/PlanAssembler.java,PlanAssembler,getNextUpdatePlan,#,1335
Before Change
}
else {
// Send the local result counts to the coordinator.
AbstractPlanNode recvNode = SubPlanAssembler.addSendReceivePair(updateNode);
// add a sum or a limit and send on top of the union
planRoot = addSumOrLimitAndSendToDMLNode(recvNode, targetTable.getIsreplicated());
}
CompiledPlan retval = new CompiledPlan();
After Change
return getNextUpdatePlan();
}
UpdatePlanNode updateNode = new UpdatePlanNode();
//FIXME: does this assert need to be relaxed in the face of non-from-clause subquery support?
// It was not in Mike A's original branch.
assert (m_parsedUpdate.m_tableList.size() == 1);
Table targetTable = m_parsedUpdate.m_tableList.get(0);
updateNode.setTargetTableName(targetTable.getTypeName());
// set this to false until proven otherwise
updateNode.setUpdateIndexes(false);
TupleAddressExpression tae = new TupleAddressExpression();
NodeSchema proj_schema = new NodeSchema();
// This planner-generated column is magic.
proj_schema.addColumn(
AbstractParsedStmt.TEMP_TABLE_NAME,
AbstractParsedStmt.TEMP_TABLE_NAME,
"tuple_address", "tuple_address",
tae);
// get the set of columns affected by indexes
Set<String> affectedColumns = getIndexedColumnSetForTable(targetTable);
// add the output columns we need to the projection
//
// Right now, the EE is going to use the original column names
// and compare these to the persistent table column names in the
// update executor in order to figure out which table columns get
// updated. We'll associate the actual values with VOLT_TEMP_TABLE
// to avoid any false schema/column matches with the actual table.
for (Entry<Column, AbstractExpression> colEntry :
m_parsedUpdate.columns.entrySet()) {
Column col = colEntry.getKey();
String colName = col.getTypeName();
AbstractExpression expr = colEntry.getValue();
expr.setInBytes(colEntry.getKey().getInbytes());
proj_schema.addColumn(
AbstractParsedStmt.TEMP_TABLE_NAME,
AbstractParsedStmt.TEMP_TABLE_NAME,
colName, colName,
expr);
// check if this column is an indexed column
if (affectedColumns.contains(colName)) {
updateNode.setUpdateIndexes(true);
}
}
ProjectionPlanNode projectionNode =
new ProjectionPlanNode(proj_schema);
// add the projection inline (TODO: this will break if more than one
// layer is below this)
//
// When we inline this projection into the scan, we're going
// to overwrite any original projection that we might have inlined
// in order to simply cull the columns from the persistent table.
assert(subSelectRoot instanceof AbstractScanPlanNode);
subSelectRoot.addInlinePlanNode(projectionNode);
// connect the nodes to build the graph
updateNode.addAndLinkChild(subSelectRoot);
CompiledPlan retval = new CompiledPlan();
retval.setReadOnly (false);
if (targetTable.getIsreplicated()) {
retval.replicatedTableDML = true;
}
//FIXME: This assumption was only safe when we didn't support updates
// w/ possibly non-deterministic subqueries.
// Is there some way to integrate a "subquery determinism" check here?
// because we didn't support updates with limits, either.
// Since the update cannot be inherently non-deterministic, there is
// no message, and the last parameter is null.
retval.statementGuaranteesDeterminism(false, true, null);
if (m_partitioning.wasSpecifiedAsSingle() || m_partitioning.isInferredSingle()) {
retval.rootPlanGraph = updateNode;
return retval;
}
// Send the local result counts to the coordinator.
// Add a compensating sum of modified tuple counts or a limit 1
// AND a send on top of the union-like receive node.
boolean isReplicated = targetTable.getIsreplicated();
retval.rootPlanGraph = addCoordinatorToDMLNode(updateNode, isReplicated);
return retval;
}